0%

实现strStr()

28.实现strStr() [简单]

题目说明

Leetcode题目链接

实现 strStr() 函数。

给你两个字符串 haystackneedle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

说明:

needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

示例 1:

1
2
输入:haystack = "hello", needle = "ll"
输出:2

示例 2:

1
2
输入:haystack = "aaaaa", needle = "bba"
输出:-1

示例 3:

1
2
输入:haystack = "", needle = ""
输出:0

提示:

  • 0 <= haystack.length, needle.length <= 5 * 10000
  • haystackneedle 仅由小写英文字符组成

解题思路

KMP算法

九章说不考,暂缓

暴力枚举

遍历 haystack 的每个字符,以其为起点,后面的needle.size() 个字符和 needle 逐一比较。

  • 时间复杂度:O(n*m)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
int strStr(string haystack, string needle) {
if (needle.empty())
{
return 0;
}

int needle_size = needle.size();
for (int i = 0; i < haystack.size(); i++)
{
if (haystack.size() - i < needle_size)
{
break;
}

bool equal = true;

for (int j = 0; j < needle.size(); j++)
{
if (haystack[i + j] != needle[j])
{
equal = false;
break;
}
}

if (equal)
{
return i;
}
}

return -1;
}
};

Rabin-Karp算法

在枚举中,每次都需要比较needle的每一个字符,那么如果可以把字符串比较转化为数值比较,就可以加速整个比较过程 —— 使用 Hashcode

1
2
3
4
5
hashcode("abcd") = a * 31^3 + b * 31^2 + c * 31^1 + d

// abcd - > bcde
hashcode("abcde") = hashcode("abcd") * 31 + e
hashcode("bcde") = hashcode("abcde") - a * 31^4

另外需要一个足够大的 BASE 用于取余。

  • 时间复杂度:O(n+m)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Solution {
private:
const int BASE = 100007;
const int TIMES = 31;

public:
int strStr(string haystack, string needle) {
if (needle.empty())
{
return 0;
}

const int needle_size = needle.size();
if (haystack.size() < needle_size)
{
return -1;
}

int power = 1;
for (int i = 0; i < needle_size; i++)
{
power = power * TIMES % BASE;
}

int needle_code = 0;
for (int i = 0; i < needle_size; i++)
{
needle_code = (needle_code * TIMES + needle[i]) % BASE;
}

int code = 0;
for (int i = 0; i < haystack.size(); i++)
{

// add new
code = (code * TIMES + haystack[i]) % BASE;
if (i < needle_size - 1)
{
continue;
}

// delete first
if (i >= needle_size)
{
code -= haystack[i - needle_size] * power % BASE;
if (code < 0)
code += BASE;
}

// 其实需要再验证一下
if (code == needle_code)
{
return (i - needle_size + 1);
}
}

return -1;
}
};